#ifndef RTPPARSE_RTP_STREAM_RECV_H
#define RTPPARSE_RTP_STREAM_RECV_H

#include <vector>
#include <memory>

#include "rtp/RtpStream.h"
#include "rtp/NackGenerator.h"
#include "TimerHandle.h"
#include "rtp/Packet.h"
#include "rtp/RateCalculator.h"
#include "rtp/RtpPacket.h"


namespace Rtp {
    class RtpStreamRecv : public RtpStream, 
                            public NackGenerator::Listener,
                            public ::TimerHandle::Listener {
    public:
        class Listener: public RtpStream::Listener {
        public:
            virtual void OnRtpStreamSendRtcpPacket(Rtp::RtpStreamRecv *rtpStream, Rtp::Rtcp::Packet *packet) = 0;
            virtual void OnRtpStreamNeedWorstRemoteFractionLost(Rtp::RtpStreamRecv *rtpStream, uint8_t& worstRemoteFractionLost) = 0;
        };

    public:
        class TransmissionCounter {
        public:
            TransmissionCounter(uint8_t spatialLayers, uint8_t temporalLayers, size_t windowSize);
            void Update(Rtp::RtpPacket* packet);
			uint32_t GetBitrate(uint64_t nowMs);
			uint32_t GetBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer);
			uint32_t GetSpatialLayerBitrate(uint64_t nowMs, uint8_t spatialLayer);
			uint32_t GetLayerBitrate(uint64_t nowMs, uint8_t spatialLayer, uint8_t temporalLayer);
			size_t GetPacketCount() const;
			size_t GetBytes() const;
        private:
            std::vector<std::vector<Rtp::RtpDataCounter>> spatialLayerCounters;
        };
    public:
        RtpStreamRecv(Rtp::RtpStreamRecv::Listener *listener,
        Rtp::RtpStream::Params& params, unsigned int sendNackDelayMs, bool useRtpInactivityCheck);
        ~RtpStreamRecv() override;

        bool ReceivePacket(Rtp::RtpPacket *packet);
    private:
        void CalculateJitter(uint32_t rtpTimestamp);
        

    private:
        unsigned int sendNackDelaysMs{ 0u };
        bool useRtpInactivityCheck{ false };

        uint32_t expectedPrior { 0u };
        uint32_t expectedPriorScore { 0u };
        uint32_t receivedPrior { 0u };
        uint32_t receivePriorScore { 0u };
        uint32_t lastSrTimestamp { 0u };
        uint64_t lastSrReceived { 0u };
        int32_t transit { 0u };

        float jitter { 0 };
        uint8_t firSeqNumber { 0u };
        uint32_t reportedPacketLost { 0u };
        std::unique_ptr<Rtp::NackGenerator> nackGenerator;
        TimerHandle *inactivityCheckPeriodicTimer { nullptr };
        bool inactive { false };

        TransmissionCounter transmissionCounter;
        Rtp::RtpDataCounter mediaTransmissionCounter;
    };
}


#endif